#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
#include "esp_timer.h"
#include "esp_log.h"

#include "storage.h"
#include "button.h"

#define TAG "Button"

#define GPIO_INPUT_KEY     12
#define GPIO_INPUT_PIN_SEL  (1ULL<<GPIO_INPUT_KEY)

#define ESP_INTR_FLAG_DEFAULT 0

#define SHORT_PRESS_MS      100 * 1000           // 短按消抖时间（毫秒）
#define LONG_PRESS_MS       5000 * 1000         // 长按判定时间（毫秒）
#define MULTI_PRESS_GAP_MS  2000 * 1000          // 连按间隔时间（毫秒）

static QueueHandle_t button_event_queue = NULL;

extern uint8_t bluetooth_flag;
extern uint8_t need_reboot;
extern uint8_t identifyBuf[32];

app_key_t appKey;

static void IRAM_ATTR gpio_isr_handler(void* arg)
{
    uint32_t press_duration = 0;
    uint32_t now = 0;
    button_event_t event;

    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    now = esp_timer_get_time();//pdTICKS_TO_MS(xTaskGetTickCount());
    if(0 == gpio_get_level(GPIO_INPUT_KEY))
    {
        appKey.last_press_time = now;
    }
    else
    {
        appKey.press_count++;
        
        // press_duration = now - appKey.last_press_time;

        // if (press_duration >= LONG_PRESS_MS)
        // {
        //     event = BUTTON_EVENT_LONG_PRESS;
        // } 
        // else if (press_duration >= SHORT_PRESS_MS)
        // {
        //     if ((now - appKey.last_press_time) < MULTI_PRESS_GAP_MS) {
        //         appKey.press_count++;
        //     } else {
        //         appKey.press_count = 1;
        //     }
        //     // 连按次数判断（例如：双击、三击）
        //     if (appKey.press_count >= 2) {
        //         event = BUTTON_EVENT_MULTI_PRESS;
        //     } else {
        //         event = BUTTON_EVENT_SHORT_PRESS;
        //     }
        // }
        event = SHORT_PRESS_MS;
        xQueueSendFromISR(button_event_queue, &event, &xHigherPriorityTaskWoken);
    }

     if (xHigherPriorityTaskWoken) {
         portYIELD_FROM_ISR();
    }
}

static void gpioKeyTask(void* arg)
{
    uint32_t current = 0;
    uint32_t duration = 0;
    button_event_t event;
    for (;;) {
        if(xQueueReceive(button_event_queue, &event, portMAX_DELAY)) 
        {
            duration = esp_timer_get_time() - appKey.last_press_time;
            if(duration >= LONG_PRESS_MS)
            {
                printf("LLLLLLLLL\r\n");
                appKey.press_count = 0;
                
                writeConfigToNvs(nvs_ssid, strlen(nvs_ssid), "", 0);
                writeConfigToNvs(nvs_pwd, strlen(nvs_pwd), "", 0);
                writeConfigToNvs(nvs_identify, strlen(nvs_identify), "", 0);
                need_reboot = 1;
            }
            
            printf(" %d  \r\n", appKey.press_count);
        

            switch (event){
                case BUTTON_EVENT_SHORT_PRESS:
                    ESP_LOGI(TAG, "Short press");
                    // appKey.press_count = 0;
                    break;
                case BUTTON_EVENT_LONG_PRESS:
                    ESP_LOGI(TAG, "Long press");
                    // appKey.press_count = 0;
                    // writeConfigToNvs(nvs_ssid, strlen(nvs_ssid), "", 0);
                    // writeConfigToNvs(nvs_pwd, strlen(nvs_pwd), "", 0);
                    // writeConfigToNvs(nvs_identify, strlen(nvs_identify), "", 0);
                    // need_reboot = 1;
                    break;
                case BUTTON_EVENT_MULTI_PRESS:
                    ESP_LOGI(TAG, "More click(count:%d)", appKey.press_count);
                    appKey.press_count = 0;
                    // bluetooth_flag = 0;
                    // memset(identifyBuf, 0 , sizeof(identifyBuf));
                    // writeConfigToNvs(nvs_identify, strlen(nvs_identify), "", 0);
                    break;
                default:
                    break;
            }
            ESP_LOGI(TAG, "---- %ld",  appKey.last_press_time);

            // appKey.last_press_time = 0;
        }
    }
}

void gpioInit(void)
{
    gpio_config_t io_conf = {};
    //interrupt of rising edge
    io_conf.intr_type = GPIO_INTR_POSEDGE;
    //bit mask of the pins, use GPIO4/5 here
    io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
    //set as input mode
    io_conf.mode = GPIO_MODE_INPUT;
    //enable pull-up mode
    io_conf.pull_up_en = 1;
    io_conf.pull_down_en = 0;
    gpio_config(&io_conf);

    button_event_queue = xQueueCreate(5, sizeof(button_event_t));
    //start gpio task
    xTaskCreate(gpioKeyTask, "gpioKeyTask", 2048, NULL, 5, NULL);
    //install gpio isr service
    gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
    //hook isr handler for specific gpio pin
    gpio_isr_handler_add(GPIO_INPUT_KEY, gpio_isr_handler, (void*) GPIO_INPUT_KEY);
}